<!--头部搜索条件工具栏布局组件-->
<template>
  <div class="c-header-box">
    <!--  条件区域  -->
    <div v-if="conditionVisible" class="c-header-box-top" :style="{'padding-bottom':bottomVisible?'10px':'0px'}">
      <div ref="conditionRef" :style="{width:conditionWidth+'px'}">
        <slot></slot>
      </div>
      <div class="c-header-box-top-button" :style="{width:buttonWidth+'px'}">
        <div ref="buttonRef" :style="{width:!isModal?(buttonAreaWidth+'px'):'auto'}" :class="{'c-header-box-top-button-area':true,'c-header-box-top-button-left':moreThanOneRow}">
          <span>
            <slot name="customButton"></slot>
          </span>
          <div v-if="!bottomVisible">
            <slot name="rightButtons"></slot>
          </div>
        </div>
      </div>
    </div>
    <!--  分隔线  -->
    <div v-if="conditionVisible&&bottomVisible" class="c-header-box-line"></div>
    <!--  自定义  -->
    <div v-if="!conditionVisible&&!bottomVisible&&customArea"><slot></slot></div>
    <!--  底部条件区域  -->
    <div v-if="bottomVisible" :class="{'c-header-box-buttons-rule':true,'c-header-box-bottom':conditionVisible,'c-header-box-bottom-only':!conditionVisible}">
      <div>
        <slot name="buttons"></slot>
      </div>
      <div>
        <slot name="rightButtons"></slot>
      </div>
    </div>
  </div>
</template>

<script>
import './index.less'
export default {
  name: 'AntHeaderToolBar',
  props: {
    /**
     * 条件区是否显示
     */
    conditionVisible: {
      type: Boolean,
      default: true
    },
    /**
     * 底部条件区域是否展示
     */
    bottomVisible: {
      type: Boolean,
      default: true
    },
    /**
     * 自定义区域是否展示 - 需关闭条件区域和底部条件区域
     */
    customArea: {
      type: Boolean,
      default: false
    },
    /**
     * 应用场景 是否为modal
     */
    isModal: {
      type: Boolean,
      default: false
    },
    /**
     * 是否仅有一行条件区域
     */
    onlyOneRow: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 条件区宽度 - 自动计算
      conditionWidth: document.body.clientWidth,
      // 按钮区域宽度
      buttonWidth: 0,
      // 按钮显示区域宽度
      buttonAreaWidth: 240,
      // 条件输入框是否超过一行
      moreThanOneRow: false
    }
  },
  computed: {
    /**
     * 获取弹框的最大可视看睹
     * @returns {number}
     */
    getModalMaxWidth() {
      return document.body.clientWidth - 232
    }
  },
  mounted() {
    const _this = this
    if (!this.conditionVisible) {
      return
    }
    // 监听头部条件区域宽度变化
    const rootRo = new ResizeObserver(entries => {
      this.$nextTick(() => {
        // 1.初始化计算 - 因按钮区域已加载完毕
        _this.reloadFormWidth()
      })
    })
    rootRo.observe(this.$refs.conditionRef.parentNode)
    // 2.监听按钮区域变动 - 可能存在按钮动态隐藏、显示情况
    const observer = new MutationObserver((mutationsList, observer) => {
      // 在每次 DOM 变化时触发的回调函数
      for (const mutation of mutationsList) {
        if (mutation.type === 'childList') {
          this.$nextTick(() => {
            // 子节点列表变化（添加或删除子节点）
            _this.reloadFormWidth()
          })
        }
      }
    })
    // 配置 MutationObserver
    const config = { childList: true, subtree: true }
    // 开始观察目标节点
    observer.observe(this.$refs.buttonRef, config)
  },
  methods: {
    /**
     * 计算表单宽度
     */
    reloadFormWidth() {
      this.buttonWidth = null
      let conditionWidth = 0
      const condition = this.$refs.conditionRef
      if (condition) {
        // 1.获取按钮宽度
        let buttonWidth = 0
        for (let i = 0; i < this.$refs.buttonRef.children.length; i++) {
          buttonWidth += this.getDomWidth(this.$refs.buttonRef.children[i])
        }
        this.buttonWidth = buttonWidth
        if (!this.onlyOneRow) {
          this.moreThanOneRow = !!((condition.clientHeight / 52) > 1)
        }
        const totalWidth = (this.isModal ? this.getModalMaxWidth : this.getDomWidth(condition.parentNode)) - buttonWidth
        for (let i = 0; i < condition.children.length; i++) {
          // 宽度监听到表单子级，避免宽度计算错误
          const width = this.getDomChildWidth(condition.children[i])
          if ((conditionWidth + width) <= totalWidth) {
            conditionWidth += width
          }
        }
        this.conditionWidth = totalWidth <= 0 ? this.getModalMaxWidth : conditionWidth + 1
        this.buttonAreaWidth = this.getDomWidth(condition.parentNode) - this.conditionWidth + (this.moreThanOneRow ? 16 : 0)
      }
    },
    /**
     * 获取元素实际宽度
     * @param dom
     * @returns {number|number|*|number}
     */
    getDomWidth(dom) {
      let oStyle = dom.currentStyle ? dom.currentStyle : window.getComputedStyle(dom, null)
      const width = parseFloat(oStyle.width)
      return !width ? dom.offsetWidth : width
    },
    /**
     * 获取dom子元素的宽度
     * @param dom
     * @returns {number}
     */
    getDomChildWidth(dom) {
      let width = 0
      for (let i = 0; i < dom.children.length; i++) {
        width += this.getDomWidth(dom.children[i])
      }
      // 获取当前dom的外边距
      let oStyle = dom.currentStyle ? dom.currentStyle : window.getComputedStyle(dom, null)
      const paddingRight = parseFloat(oStyle.paddingRight)
      return width + paddingRight
    }
  }
}
</script>

<style lang="less" scoped>
.c-header-box{
  display: flex;
  flex-flow: column nowrap;
  justify-content: flex-start;
  .c-header-box-top{
    display: flex;
    flex-flow: row nowrap;
    justify-content: flex-start;
    .c-header-box-top-button{
      position: relative;
      line-height: 52px;
      .c-header-box-top-button-area{
        position: absolute;
        display: flex;
        flex-flow: row nowrap;
        justify-content: space-between;
        span{
          > button{
            margin: 0px 16px 0px 0px;
          }
          > button:last-child{
            margin:0px;
          }
        }
        >div{
          padding-top:10px;
        }
      }
      .c-header-box-top-button-left{
        margin-left: -16px;
      }
    }
    .ant-form-item{
      padding-right:32px;
    }
    .ant-form-item:last-child{
      padding-right:16px;
    }
  }
  .c-header-box-line{
    height: 0px;
    border-bottom: 1px solid #E6E6E6;
  }
  .c-header-box-buttons-rule{
    display: flex;
    flex-flow: row nowrap;
    justify-content: space-between;
    div{
      display: flex;
      flex-flow: row nowrap;
      justify-content: flex-start;
      .ant-btn{
        margin: 0px 16px 0px 0px;
      }
      .ant-btn:last-child{
        margin: 0px 0px 0px 0px;
      }
    }
  }
  .c-header-box-bottom{
    margin:20px 0px 10px 0px;
  }
  .c-header-box-bottom-only{
    margin:10px 0px 10px 0px;
  }
}
</style>
